﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DynaPrecision.CommonCollection
{
	public class SubList<TList, T> : IList<T>
		where TList : IList<T>
	{
		public int StartIndex { get; set; }
		public int EndIndex { get; set; }

		public TList UnderlyingList { get; set; }


		bool _isInRange(int i)
		{
			return StartIndex <= i && i <= EndIndex;
		}
		#region IList<T> Members

		public int IndexOf(T item)
		{
			var r = UnderlyingList.IndexOf(item);
			if (_isInRange(r))
			{
				return r - StartIndex;
			}
			else
			{
				return -1;
			}
		}

		public void Insert(int index, T item)
		{
			if (_isInRange(index + StartIndex))
			{
				UnderlyingList.Insert(index + StartIndex, item);
				EndIndex += 1;
			}
		}

		public void RemoveAt(int index)
		{
			UnderlyingList.RemoveAt(index + StartIndex);
			EndIndex -= 1;
		}

		public T this[int index]
		{
			get
			{
				return UnderlyingList[index + StartIndex];
			}
			set
			{
				UnderlyingList[index + StartIndex] = value;
			}
		}

		#endregion

		#region ICollection<T> Members

		public void Add(T item)
		{
			this.UnderlyingList.Insert(EndIndex, item);
			EndIndex++;
		}

		public void Clear()
		{
			while (StartIndex < EndIndex)
			{
				this.RemoveAt(StartIndex);
			}
		}

		public bool Contains(T item)
		{
			if (UnderlyingList.Contains(item))
			{
				if (_isInRange(UnderlyingList.IndexOf(item)))
				{
					return true;
				}
				else
				{
					return false;
				}
			}
			else
			{
				return false;
			}
		}

		public void CopyTo(T[] array, int arrayIndex)
		{
			for (int i = 0; i < this.Count; i++)
			{
				array[arrayIndex + i] = this[i];
			}
		}

		public int Count
		{
			get { return EndIndex - StartIndex + 1; }
		}

		public bool IsReadOnly
		{
			get { return false; }
		}

		public bool Remove(T item)
		{
			if (this.Contains(item))
			{
				UnderlyingList.Remove(item);
				EndIndex--;
				return true;
			}
			else
			{
				return false;
			}
		}

		#endregion

		#region IEnumerable<T> Members

		public IEnumerator<T> GetEnumerator()
		{
			for (int i = 0; i < this.Count; i++)
			{
				yield return this[i];
			}
		}

		#endregion

		#region IEnumerable Members

		System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
		{
			for (int i = 0; i < this.Count; i++)
			{
				yield return this[i];
			}
		}

		#endregion
	}
}
